import { isFunction, snakeCase } from 'lodash';
import { FrameworkConfiguration } from './interfaces';
export function toArray(array) {
  return Array.isArray(array) ? array : [array];
}
export function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}
export function nextTick(cb) {
  Promise.resolve().then(cb);
}
export function isConstructable(fn) {
  const constructableFunctionRegex = /^function\b\s[A-Z].*/;
  const classRegex = /^class\b/;
  return fn.prototype && fn.prototype.constructor === fn && Object.getOwnPropertyNames(fn.prototype).length > 1 || constructableFunctionRegex.test(fn.toString()) || classRegex.test(fn.toString());
}
const naughtySafari = typeof document.all === 'function' && typeof document.all === 'undefined';
export const isCallable = naughtySafari ? fn => typeof fn === 'function' && typeof fn !== 'undefined' : fn => typeof fn === 'function';
export function isBoundedFunction(fn) {
  return fn.name.indexOf('bound ') === 0 && !fn.hasOwnProperty('prototype');
}
export function uniq(array) {
  return array.filter(function filter(element) {
    return element in this ? false : this[element] = true;
  }, {});
}
export function getDefaultTplWrapper(id, name) {
  return tpl => `<div id="${getWrapperId(id)}" data-name="${name}">${tpl}</div>`;
}
export function getWrapperId(id) {
  return `__qiankun_microapp_wrapper_for_${snakeCase(id)}__`;
}
export function validateExportLifecycle(exports) {
  const {
    bootstrap,
    mount,
    unmount
  } = exports ?? {};
  return isFunction(bootstrap) && isFunction(mount) && isFunction(unmount);
}

class Deferred {
  constructor() {
    this.promise = new Promise((resolve, reject) => {
      this.resolve = resolve;
      this.reject = reject;
    });
  }

}

export { Deferred };
const supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function';
export function performanceMark(markName) {
  if (supportsUserTiming) {
    performance.mark(markName);
  }
}
export function performanceMeasure(measureName, markName) {
  if (supportsUserTiming) {
    performance.measure(measureName, markName);
    performance.clearMarks(markName);
    performance.clearMeasures(measureName);
  }
}
export function isEnableScopedCSS(opt) {
  if (typeof opt.sandbox !== 'object') {
    return false;
  }

  if (opt.sandbox.strictStyleIsolation) {
    return false;
  }

  return !!opt.sandbox.experimentalStyleIsolation;
}